//! Actix-web 完整服务器示例
//! 展示如何使用 unified_api 框架构建完整的 Actix-web 应用

#[cfg(feature = "actix")]
mod actix_impl {
    use actix_web::{get, post, put, delete, web, App, HttpServer, HttpResponse, Result, middleware};
    use serde::{Deserialize, Serialize};
    use std::sync::Arc;
    
    use unified_api::{
        uni_api, auth::{JwtAuthPolicy, AuthPolicy, AuthContext, AuthRequest, AuthResult},
        routers::{RouteInfo, RouteBuilder},
        middleware::{AuthMiddleware, MiddlewareChain, LoggingMiddleware, CorsMiddleware},
        swagger::{SwaggerConfig, SwaggerGenerator}
    };

    #[derive(Debug, Serialize, Deserialize, Clone)]
    struct User {
        id: u64,
        name: String,
        email: String,
        created_at: String,
    }

    #[derive(Debug, Serialize, Deserialize)]
    struct CreateUserRequest {
        name: String,
        email: String,
    }

    #[derive(Debug, Serialize, Deserialize)]
    struct UpdateUserRequest {
        name: Option<String>,
        email: Option<String>,
    }

    // 模拟用户数据库
    struct UserDatabase {
        users: std::sync::RwLock<Vec<User>>,
    }

    impl UserDatabase {
        fn new() -> Self {
            let users = vec![
                User {
                    id: 1,
                    name: "Alice Johnson".to_string(),
                    email: "alice@example.com".to_string(),
                    created_at: "2024-01-01T00:00:00Z".to_string(),
                },
                User {
                    id: 2,
                    name: "Bob Smith".to_string(),
                    email: "bob@example.com".to_string(),
                    created_at: "2024-01-02T00:00:00Z".to_string(),
                },
            ];
            
            Self {
                users: std::sync::RwLock::new(users),
            }
        }

        fn get_all(&self) -> Vec<User> {
            self.users.read().unwrap().clone()
        }

        fn get_by_id(&self, id: u64) -> Option<User> {
            self.users.read().unwrap().iter().find(|u| u.id == id).cloned()
        }

        fn create(&self, request: CreateUserRequest) -> User {
            let mut users = self.users.write().unwrap();
            let new_id = users.len() as u64 + 1;
            let user = User {
                id: new_id,
                name: request.name,
                email: request.email,
                created_at: chrono::Utc::now().to_rfc3339(),
            };
            users.push(user.clone());
            user
        }

        fn update(&self, id: u64, request: UpdateUserRequest) -> Option<User> {
            let mut users = self.users.write().unwrap();
            if let Some(user) = users.iter_mut().find(|u| u.id == id) {
                if let Some(name) = request.name {
                    user.name = name;
                }
                if let Some(email) = request.email {
                    user.email = email;
                }
                Some(user.clone())
            } else {
                None
            }
        }

        fn delete(&self, id: u64) -> bool {
            let mut users = self.users.write().unwrap();
            let initial_len = users.len();
            users.retain(|u| u.id != id);
            users.len() < initial_len
        }
    }

    // API处理器
    #[uni_api(
        route = "/users",
        method = "GET",
        auth_policy = "permission:users.read",
        description = "获取所有用户列表",
        tags = ["users", "admin"]
    )]
    #[get("/users")]
    async fn get_users(db: web::Data<Arc<UserDatabase>>) -> Result<HttpResponse> {
        let users = db.get_all();
        
        Ok(HttpResponse::Ok().json(serde_json::json!({
            "success": true,
            "data": users,
            "total": users.len()
        })))
    }

    #[uni_api(
        route = "/users/{id}",
        method = "GET",
        auth_policy = "permission:users.read",
        description = "根据ID获取用户信息",
        tags = ["users"]
    )]
    #[get("/users/{id}")]
    async fn get_user_by_id(
        path: web::Path<u64>,
        db: web::Data<Arc<UserDatabase>>,
    ) -> Result<HttpResponse> {
        let id = path.into_inner();
        
        match db.get_by_id(id) {
            Some(user) => Ok(HttpResponse::Ok().json(serde_json::json!({
                "success": true,
                "data": user
            }))),
            None => Ok(HttpResponse::NotFound().json(serde_json::json!({
                "success": false,
                "error": "User not found"
            }))),
        }
    }

    #[uni_api(
        route = "/users",
        method = "POST",
        auth_policy = "permission:users.create",
        description = "创建新用户",
        tags = ["users", "admin"]
    )]
    #[post("/users")]
    async fn create_user(
        user_data: web::Json<CreateUserRequest>,
        db: web::Data<Arc<UserDatabase>>,
    ) -> Result<HttpResponse> {
        let user = db.create(user_data.into_inner());
        
        Ok(HttpResponse::Created().json(serde_json::json!({
            "success": true,
            "data": user,
            "message": "User created successfully"
        })))
    }

    #[uni_api(
        route = "/users/{id}",
        method = "PUT",
        auth_policy = "user:{id}",
        description = "更新用户信息",
        tags = ["users"]
    )]
    #[put("/users/{id}")]
    async fn update_user(
        path: web::Path<u64>,
        user_data: web::Json<UpdateUserRequest>,
        db: web::Data<Arc<UserDatabase>>,
    ) -> Result<HttpResponse> {
        let id = path.into_inner();
        
        match db.update(id, user_data.into_inner()) {
            Some(user) => Ok(HttpResponse::Ok().json(serde_json::json!({
                "success": true,
                "data": user,
                "message": "User updated successfully"
            }))),
            None => Ok(HttpResponse::NotFound().json(serde_json::json!({
                "success": false,
                "error": "User not found"
            }))),
        }
    }

    #[uni_api(
        route = "/users/{id}",
        method = "DELETE",
        auth_policy = "role:admin",
        description = "删除用户",
        tags = ["users", "admin"]
    )]
    #[delete("/users/{id}")]
    async fn delete_user(
        path: web::Path<u64>,
        db: web::Data<Arc<UserDatabase>>,
    ) -> Result<HttpResponse> {
        let id = path.into_inner();
        
        if db.delete(id) {
            Ok(HttpResponse::Ok().json(serde_json::json!({
                "success": true,
                "message": format!("User {} deleted successfully", id)
            })))
        } else {
            Ok(HttpResponse::NotFound().json(serde_json::json!({
                "success": false,
                "error": "User not found"
            })))
        }
    }

    #[uni_api(
        route = "/health",
        method = "GET",
        auth_policy = "",
        description = "健康检查接口",
        tags = ["health"]
    )]
    #[get("/health")]
    async fn health_check() -> Result<HttpResponse> {
        Ok(HttpResponse::Ok().json(serde_json::json!({
            "status": "healthy",
            "timestamp": chrono::Utc::now().to_rfc3339(),
            "version": "1.0.0"
        })))
    }

    // Swagger文档接口
    #[get("/docs")]
    async fn swagger_docs() -> Result<HttpResponse> {
        let config = SwaggerConfig::new("User Management API", "1.0.0")
            .with_description("A comprehensive user management API built with unified_api framework")
            .with_host("localhost:8080")
            .with_base_path("/api");

        let routes = vec![
            RouteInfo::new("/users", "GET", "get_users")
                .with_auth_policy("permission:users.read")
                .with_description("获取所有用户列表")
                .with_tags(vec!["users", "admin"]),
            RouteInfo::new("/users/{id}", "GET", "get_user_by_id")
                .with_auth_policy("permission:users.read")
                .with_description("根据ID获取用户信息")
                .with_tags(vec!["users"]),
            RouteInfo::new("/users", "POST", "create_user")
                .with_auth_policy("permission:users.create")
                .with_description("创建新用户")
                .with_tags(vec!["users", "admin"]),
            RouteInfo::new("/users/{id}", "PUT", "update_user")
                .with_auth_policy("user:{id}")
                .with_description("更新用户信息")
                .with_tags(vec!["users"]),
            RouteInfo::new("/users/{id}", "DELETE", "delete_user")
                .with_auth_policy("role:admin")
                .with_description("删除用户")
                .with_tags(vec!["users", "admin"]),
            RouteInfo::new("/health", "GET", "health_check")
                .with_auth_policy("")
                .with_description("健康检查接口")
                .with_tags(vec!["health"]),
        ];

        let generator = SwaggerGenerator::new(config).add_routes(routes);
        
        match generator.generate() {
            Ok(swagger_doc) => Ok(HttpResponse::Ok().json(swagger_doc)),
            Err(e) => Ok(HttpResponse::InternalServerError().json(serde_json::json!({
                "error": format!("Failed to generate Swagger docs: {}", e)
            }))),
        }
    }

    // 认证中间件
    async fn auth_middleware(
        req: actix_web::HttpRequest,
        next: actix_web::dev::ServiceRequest,
    ) -> Result<actix_web::dev::ServiceResponse, actix_web::Error> {
        // 跳过健康检查和文档接口的认证
        if req.path() == "/api/health" || req.path() == "/api/docs" {
            return next.call(req).await.map(|res| res.map_into_right_body());
        }

        // 检查 Authorization header
        if let Some(auth_header) = req.headers().get("Authorization") {
            if let Ok(auth_str) = auth_header.to_str() {
                if auth_str.starts_with("Bearer ") {
                    let token = &auth_str[7..];
                    
                    // 简单的token验证（实际应该使用JWT）
                    if token == "valid-jwt-token" || token == "admin-token" {
                        return next.call(req).await.map(|res| res.map_into_right_body());
                    }
                }
            }
        }

        Ok(actix_web::dev::ServiceResponse::new(
            req.into_parts().0,
            HttpResponse::Unauthorized().json(serde_json::json!({
                "success": false,
                "error": "Unauthorized",
                "message": "Valid JWT token required"
            })).into_body().into(),
        ))
    }

    #[actix_web::main]
    pub async fn main() -> std::io::Result<()> {
        println!("🚀 Starting Actix-web server with unified_api framework");
        println!("📚 Swagger docs available at: http://localhost:8080/api/docs");
        println!("🏥 Health check available at: http://localhost:8080/api/health");

        // 初始化用户数据库
        let db = Arc::new(UserDatabase::new());

        // 配置JWT认证策略
        let jwt_secret = std::env::var("JWT_SECRET").unwrap_or_else(|_| "your-secret-key".to_string());
        let auth_policy = Arc::new(JwtAuthPolicy::new(jwt_secret));

        // 配置中间件链
        let middleware_chain = MiddlewareChain::new()
            .add_middleware(Arc::new(LoggingMiddleware))
            .add_middleware(Arc::new(CorsMiddleware::default()));

        // 启动服务器
        HttpServer::new(move || {
            App::new()
                .app_data(web::Data::new(db.clone()))
                .wrap(middleware::Logger::default())
                .wrap(middleware::Condition::new(true, actix_web::middleware::Compat::new(
                    actix_web::middleware::Fn::new(auth_middleware)
                )))
                .service(
                    web::scope("/api")
                        .service(get_users)
                        .service(get_user_by_id)
                        .service(create_user)
                        .service(update_user)
                        .service(delete_user)
                        .service(health_check)
                        .service(swagger_docs)
                )
        })
        .bind("127.0.0.1:8080")?
        .run()
        .await
    }
}

#[cfg(not(feature = "actix"))]
fn main() {
    println!("This example requires the 'actix' feature to be enabled.");
    println!("Run with: cargo run --example actix_server --features actix,jwt,swagger");
}

#[cfg(feature = "actix")]
fn main() {
    actix_impl::main();
}